<template lang="html">
  <div class="ar-lists" ref="tableList" @scroll="scrollLists">
    <div class="lists-box" :style="{
        paddingTop: `${paddingTop}px`,
      }">
      <template v-for="(data, index) in allData">
        <ul class="lists" :pagenum="data[0].page" :key="index">
          <li :style="{ color: ind == data.length - 1 && 'red' }" v-for="(item, ind) in data" :key="ind">
            <span class="index">{{ item.index }}</span>{{ item.name }}
          </li>
        </ul>
      </template>
    </div>
  </div>
</template>
<script>
  import _debounce from "lodash/debounce";
  import axios from "axios";
  import qs from "qs";
  import faker from "faker";

  export default {
    data() {
      return {
        allData: [],
        paddingTop: 0,
        pageNum: 1,
      };
    },
    created() {
      this.distance = 10; // 加载个数
      this.currentPage = 1; // 上一刻的页码
      this.scrollTopPosition = 0; // 上一刻的滚动高度
      this.isScrollDown = true; // 滚动方向
      this.ulElPosition = {}; // 所有ul位置
    },
    async mounted() {
      // 初始化加载2页
      await this.queryListData(1);
      await this.queryListData(2);
      this.computedUlArea();
    },
    updated() {
      this.computedUlArea();
    },
    methods: {
      queryListData(page) {
        return new Promise((resovle, reject) => {
          let lists = [],
            from = (page - 1) * this.distance + 1,
            to = page * this.distance;
          for (; from <= to; from++) {
            lists.push({
              index: from,
              name: faker.lorem.sentences(),
              page,
            });
          }
          this.isScrollDown ?
            this.allData.push(lists) :
            this.allData.unshift(lists);
          resovle(lists);
        });
      },
      // async queryListData (page) {
      //   const params = qs.stringify({ pageNo: page, pageSize: 20 })
      //   const { data: { data } } = await axios.post('/digitalShare/digitalProjectSurveyHeadData/getPage', params)
      //   data['list'].map((item, index) => {
      //     item.page = page
      //     item.index = (page - 1) * 20 + index + 1
      //     item.name = item.address
      //   })
      //   this.isScrollDown
      //     ? this.allData.push(data['list'])
      //     : this.allData.unshift(data['list']);
      // },
      // 计算每个ul范围
      computedUlArea() {
        return new Promise((resovle, reject) => {
          this.ulElPosition = [];
          const ulDoms = document.querySelectorAll(".lists-box .lists");
          ulDoms.forEach((dom) => {
            const ind = dom.getAttribute("pageNum");
            this.ulElPosition.push({
              top: dom.offsetTop,
              bottom: dom.offsetTop + dom.clientHeight,
              height: dom.clientHeight,
              page: ind,
            });
          });
          resovle(true)
        })
      },
      // 获取当前滚动位置
      getPageNumByScroll(scrollTop) {
        let pageNum = 0;
        this.ulElPosition.forEach((item) => {
          if (scrollTop > item["top"] && scrollTop <= item["bottom"]) {
            pageNum = item.page;
          }
        });
        return pageNum * 1;
      },
      scrollLists: _debounce(async function (e) {
        // 父级容器节点
        const listDom = this.$refs["tableList"];
        // 容器高度
        const listDomHieght = listDom.clientHeight * 1;
        // 判断滚动方向
        this.isScrollDown = listDom.scrollTop - this.scrollTopPosition > 0;
        // 父级容器滚动高度
        this.scrollTopPosition = listDom.scrollTop * 1;
        // 获取当前可是区域底部滚动位置对应的页码
        const currentPage = this.getPageNumByScroll(
          this.scrollTopPosition + listDomHieght
        );
        console.log(currentPage, this.scrollTopPosition + listDomHieght, this.ulElPosition)
        if (!currentPage) return
        // 如果是向下滚动
        if (this.isScrollDown) {
          // 当ul数量等于3时，并且当前滚动距离等于第一个ul底部距离
          if (
            this.scrollTopPosition + listDomHieght >=
            this.ulElPosition[this.ulElPosition.length - 1].top
          ) {
            const ulDoms = document.querySelectorAll(".lists-box .lists");
            if (ulDoms.length == 3) {
              // 删除第一个ul
              this.allData.shift();
              // 使用paddingTop是填补删除的空位，避免影响滚动条位置
              this.paddingTop = this.paddingTop + this.ulElPosition[0].height;
            }
            if (currentPage > this.currentPage) {
              this.currentPage = currentPage;
              await this.queryListData(currentPage + 1);
            }
          }
        } else {
          if (currentPage < this.currentPage && currentPage == this.ulElPosition[0].page) {
            this.currentPage = currentPage;
            if (currentPage - 1 >= 1) {
              await this.queryListData(currentPage - 1);
              this.$nextTick(async () => {
                const firstUlDom = document.querySelector(".lists-box .lists")
                const paddingTop = this.paddingTop - firstUlDom.clientHeight * 1
                this.allData.pop()
                this.paddingTop = paddingTop > 0 ? paddingTop : 0
              })
            }
          }
        }
      }, 200),
    },
  };

</script>
<style scoped lang="less">
  .ar-lists {
    width: 300px;
    height: 600px;
    border: 1px solid #e6e6e6;
    overflow-y: scroll;
    position: relative;
    margin: 100px auto;
    background: #f5f5f5;

    .lists {
      width: 100%;
      display: flex;
      flex-flow: column nowrap;
      padding: 0;
      margin: 0;

      li {
        width: 100%;
        border-bottom: 1px solid #e6e6e6;
        padding: 10px;
        font-size: 14px;
        color: #666;
        list-style: none;
        box-sizing: border-box;

        .index {
          color: red;
          margin-right: 15px;
          font-size: 14px;
        }
      }
    }
  }

</style>
